지금부터 알아볼 메서드는 다음과 같다.(메서드와 함수의 차이를 모르겠다면 자바스크립트 기본설명을 참조 하세요)
| 메서드 | 기능개요 |
|---|---|
| bind | 다른 오브젝트의 메소드를 결합 하여 내 메소드인것처럼 사용할수 있다. |
| bindAsEventListener | 지정한 엘리먼트에서 이벤트가 발생하였을때 이를 받아 실행할 이벤트 리스너를 bind한다. |
각 메소드별 예제를 들기 전에 일단 Function클래스의 확장된 메소드들을 이해하긴 위해서는 다음 3개의 네이티브 자바스크립트를 이해하고 있어야한다.
다음에 대해 자세한 예제를 살펴보고 확장메소드에 대해 알바보도록 하자.
1. shift() : 배열변수에서 시작위치의 요소를 삭제하여 반환
2. apply() : 개체의 메서드를 적용하여 다른 개체를 현재 개체로 대체 (자바스크립트에서 함수 자체는 하나의 개체다.라고 첫 부분에서 설명이 되어 있다.)
3. concat() : 두 배열변수의 조합으로 구성된 새 배열변수를 반환 (인자로 String이 넘어오거나 Array가 넘어간다. 여기서는 Array가 쓰였다)
4. arguments = 아규먼츠 개체는 이미 학습을 하였으니 충분히 이해 하고 있다고 생각한다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title> 샘플</title>
<link rel="stylesheet" href="../protoComm.css" type="text/css" />
<script language="javascript" type="text/javascript" src="prototype.js"></script>
<script language="javascript" type="text/javascript" >
function shiftFunctionTest(argVal1, argVal2, argVal3, argVal4){
var args = $A(arguments);
alert(args); //변수1,변수2,변수3,변수4,변수5,변수6
var object = args.shift();
alert(object); //변수1
alert(args); //변수2,변수3,변수4,변수5,변수6
}
shiftFunctionTest('변수1','변수2','변수3','변수4','변수5','변수6');
</script>
</head>
<body>
</body>
</html>
위 예제로 shift 와 arguments 함수들의 역활을 충분히 설명 할수 있다.
다음 예제로 concact 메소드의 역활을 살펴보면 다음과 같다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title> 샘플 </title>
<link rel="stylesheet" href="../protoComm.css" type="text/css" />
<script language="javascript" type="text/javascript" src="prototype.js"></script>
<script language="javascript" type="text/javascript" >
var myArray=new Array('사과','포도','수박');
var otherArray=new Array('1','2','3','4');
myArray.concat('aa',otherArray);
alert(myArray.concat('aa',otherArray)); //사과,포도,수박,aa,1,2,3,4
alert(myArray); //사과,포도,수박
</script>
</head>
<body>
</body>
</html>
위의 예제에서 중요하게 살펴볼것은 myArray 이다 concat를 통하여 결합을 하였다고는 하지만 concat가 myArray 객체 자체의 값을 바꾼건 아니다 라는걸 확인 할수 있다.
이번에는 apply에 대해서 살펴 보자
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title> 샘플</title>
<link rel="stylesheet" href="../protoComm.css" type="text/css" />
<script language="javascript" type="text/javascript" src="prototype.js"></script>
<script language="javascript" type="text/javascript" >
function Person(pName,gender,birth){ // 기능함수를 만든다. Person 은 기능함수 개체이다.
this.pName=pName; // 받은 인수를 개체 속성에 할당한다. this 는 callPerson 기능함수 개체(myPerson)를 참조한다.
this.gender=gender;
this.birth=birth;
}
function callPerson(IdNumb,pName,gender,birth){ // 기능함수를 만든다.
this.IdNumb=IdNumb; // 받은 인수를 개체 속성에 할당한다.
Person.apply(this,new Array(pName,gender,birth)); // 속성들의 배열변수를 기능함수 Person에 전달한다.
}
myPerson=new callPerson(12345,'홍길동','남',1900);
document.write('호출한 사람은 ('+myPerson.pName +', '+myPerson.gender +', '+myPerson.birth +')이다.')
</script>
</head>
<body>
</body>
</html>
//[functionObj].apply([thisObj[,arguArray]]) 이런 형태로 호출 되면 첫번재 인자는 오브젝트 두번재 인자는 arguments 같은 배열이 와야 한다.
위에 기술된 apply 메소드는 bind 메소드가 가능하기 위한 핵심이다. 왜 이러한 (bind)메소드를 사용하냐 객체지향 자바스크립트를 구현 함에 있어
this에 영향을 받아 function 기준으로 볼때 같은 이름의 변수를 서로 다르게 처리 하지 않게 하기위해 사용 된다.
| 구분 | 설명 |
|---|---|
| 이름 | Function.bind() |
| 아규먼트 | Object this 오브젝트 ( object: 메소드를 소유하는 객체 ) |
| 반환 | 오브젝트를 바인드한 함수 |
var obj = {
name: 'A nice demo',
fx: function() {
alert(this.name);
}
};
window.name = 'I am such a beautiful window!';
function runFx(f) {
f();
}
var fx2 = obj.fx.bind(obj);
runFx(obj.fx); //어떻게 나올지는 코딩해 보기전에 상상해 보자
runFx(fx2); //this연산자가 어떤오브젝트를 참조하고 있냐에 따라 달리 나온다.
이번에는 응용예제를 보자 자바스크립트의 장점이자 단점이..바로 아규먼트수가 고정되어 있지 않다는거다. 다른 언어에서는 이를 처리 하기 위해 오버로딩 기법을 사용 하지만
자바스크립트에서는 그냥 쓰면 된다..물론 호출되는 메서드에 아규먼트를 우동적으로 처리 하게 준비 해야 하지만... 자바스크립트는 *아규먼트 타입과 수에 제한을 받지 않는다
이 점을 이용한 예제를 살펴 보자.
var obj = {
name: 'A nice demo',
fx: function() {
alert(this.name + '\n' + $A(arguments).join(', '));
}
};
var fx2 = obj.fx.bind(obj, 1, 2, 3);
fx2(4, 5); // 마찬가지로 결과를 상상하여 보자
bind의 의도는 Scope제한을 넘어서 서로 다른 오브젝트 간에 필요에 의해 메소드가 필요할때 결합 하기 위한 용도로 사용된다.
bind: function() {
if (arguments.length < 2 && arguments[0] === undefined) return this;
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Function 클래스</title>
<link rel="stylesheet" href="../protoComm.css" type="text/css" />
<script language="javascript" type="text/javascript" src="../prototype.js"></script>
<script language="javascript" type="text/javascript">
Event.observe(window, 'load', function() {
Event.observe('firstCheck', 'click', Show.showSport.bindAsEventListener(this, '설악산'));
Event.observe('secondCheck', 'click', Show.showSport.bindAsEventListener(this, '한라산'));
});
var Show = {
showSport: function(event, check) {
var clickElement = Event.element(event);
$('show1').innerHTML = '클릭 ID : ' + clickElement.id + ', ' + check;
}
}
</script>
</head>
<body>
<h1>bindAsEventListener() 함수</h1>
<div id="firstDivision">
<p>라디오 버튼을 선택하세요</p>
산 선택 :
<input type="radio" id="firstCheck" name="mtnName" value="1" />
<label for="firstCheck">설악산</label>
<input type="radio" id="secondCheck" name="mtnName" value="2" />
<label for="secondCheck">한라산</label>
<br /><br /><br />
<div id="showArea">
<div id="show1"></div>
<div id="show2"></div>
</div>
</div>
</body>
</html>
Event.observe('firstCheck', 'click', Show.showSport.bindAsEventListener(this, '설악산'));
Event.observe('secondCheck', 'click', Show.showSport.bindAsEventListener(this, '한라산'));
위와 같이 처리됨으로 인해
Show.showSport 메소드에는 설악산과 한라산에 대한 맞춘 코드 즉 하드코딩을 줄임으로서 코드의 재사용성을 높일수 있다.